package com.qianyu.entity.base;


import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.qianyu.enumerate.AppHttpCodeEnum;
import com.qianyu.enumerate.ResultEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

/**
 * @author hehao
 */
@Data
@NoArgsConstructor
@JsonAutoDetect
public class Result<T> implements Serializable {

    private static final long serialVersionUID = 7498483649536881777L;

    /**
     * 返回最终成功和失败的状态:0 失败; 1：成功(默认) ,有些可能是其他的状态码
     */
    @ApiModelProperty(value = "返回最终成功和失败的状态:0 失败; 1：成功(默认) ,有些可能是其他的状态码")
    private String status = "1";

    /**
     * 后端指定返回给前端的消息
     */
    @ApiModelProperty(value = "后端指定返回给前端的消息")
    private String message;

    /**
     * 后端指定返回给前端的消息
     */
    @ApiModelProperty(value = "状态码 0 成功 其它 为失败")
    private Integer code = 0;

    /**
     * 翻译后的消息
     */
    @ApiModelProperty("翻译后的消息")
    private String msgTranslation;

    /**
     * 具体的内容
     */
    @ApiModelProperty("具体的内容")
    private T data;

    /**
     * 成功时候的调用-空参数
     */
    public static <T> Result<T> success() {
        return new Result<>(true);
    }

    /**
     * 成功时候的调用-返回数据
     */
    public static <T> Result<T> success(T data) {
        return new Result<>(data, true);
    }


//    /**
//     * 成功时候的调用-自定义返回消息
//     */
//    public static <T> Result<T> success(String message) {
//        return new Result<>(message, true);
//    }

    /**
     * 成功时候的调用-自定义返回消息+返回数据
     */
    public static <T> Result<T> success(String message, T data) {
        return new Result<>(message, data, true);
    }

    /**
     * 失败的调用-空参数
     */
    public static <T> Result<T> error() {
        return new Result<>(false);
    }


    /**
     * 失败的调用-自定义返回消息
     */
    public static <T> Result<T> error(String message) {
        return new Result<>(message, false);
    }

    /**
     * 失败的调用-自定义返回消息+code
     */
    public static <T> Result<T> error(Integer code, String message) {
        return new Result<>(code, message, null,false);
    }

    /**
     * 失败的调用-自定义返回消息+返回数据
     */
    public static <T> Result<T> error(String message, T data) {
        return new Result<>(message, data, false);
    }

    /**
     * 失败自定义异常
     *
     * @param enums
     * @param <T>
     * @return
     */
    public static <T> Result<T> error(AppHttpCodeEnum enums) {
        return setAppHttpCodeEnum(enums, enums.getErrorMessage());
    }

    public static <T> Result<T> error(AppHttpCodeEnum enums, String errorMessage) {
        return setAppHttpCodeEnum(enums, errorMessage);
    }

    private static <T> Result<T> setAppHttpCodeEnum(AppHttpCodeEnum enums, String errorMessage) {
        return new Result<>(enums.getCode(), errorMessage, false);
    }

    /**
     * 灵活度更高-控制返回状态+消息+数据
     */
    public static <T> Result<T> build(String status, String message, T data) {
        return new Result<T>(status, message, data);
    }

    /**
     * 灵活度更高-使用枚举返回，不能自定义
     */
    public static <T> Result<T> build(ResultEnum resultEnum) {
        return new Result<>(resultEnum);
    }

    /**
     * 灵活度更高-使用枚举返回，可以自定义返回数据
     */
    public static <T> Result<T> build(ResultEnum resultEnum, T data) {
        return new Result<>(resultEnum, data);
    }

    /**
     * 灵活度更高-使用枚举返回，可以自定义返回消息
     */
    public static <T> Result<T> build(ResultEnum resultEnum, String message) {
        return new Result<>(resultEnum, message);
    }

    /**
     * 灵活度更高-使用枚举返回，可以自定义返回消息+数据
     */
    public static <T> Result<T> build(ResultEnum resultEnum, String message, T data) {
        return new Result<>(resultEnum, message, data);
    }

    /**
     * 根据程序执行结果-int值(1成功，0失败)，返回对应的返回成功或失败消息
     */
    public static <T> Result<T> build(Integer excuteState) {
        return excuteState == 1 ? success() : error();
    }

//    /**
//     * 根据程序执行结果-int值(1成功，0失败)，返回成功或失败消息+自定义消息
//     */
//    public static <T> Result<T> build(Integer excuteState, String message) {
//        return excuteState == 1 ? success(message) : error(message);
//    }


    /**
     * 根据程序执行结果-int值(1成功，0失败)，返回成功或失败消息+自定义消息+数据
     */
    public static <T> Result<T> build(Integer excuteState, String message, T data) {
        return excuteState == 1 ? success(message, data) : error(message, data);
    }

    /**
     * 根据程序执行结果-boolean值，返回对应的返回成功或失败消息
     */
    public static <T> Result<T> build(boolean judgeState) {
        return judgeState ? success() : error();
    }

//    /**
//     * 根据程序执行结果-boolean值，返回成功或失败消息+自定义消息
//     */
//    public static <T> Result<T> build(boolean judgeState, String message) {
//        return judgeState ? success(message) : error(message);
//    }

    /**
     * 根据程序执行结果-boolean值，返回成功或失败消息+自定义消息+数据
     */
    public static <T> Result<T> build(boolean judgeState, String message, T data) {
        return judgeState ? success(message, data) : error(message, data);
    }

    // -------------------------------------以下构造返回数据-----------------------------------------------

    /**
     * 对外返回数据
     */
    private Result(String status, String message, T data) {
        this.status = status;
        this.message = message;
        this.data = data;
    }

    /**
     * 对外返回数据
     */
    private Result(T data,boolean judge) {
        this.code = judge ? 0 : -1;
        this.status = judge ? "1" : "0";
        this.message = judge ? "成功！！！" : "失败！！！";
        this.data = data;
    }

    /**
     * 对外返回数据
     */
    private Result(Integer code, String message, T data,boolean judge) {
        this.code = code;
        this.status = judge ? "1" : "0";
        this.message = message;
        this.data = data;
    }

    private Result(boolean judge) {
        this.code = judge ? 0 : -1;
        this.status = judge ? "1" : "0";
        this.message = judge ? "成功！！！" : "失败！！！";
        this.data = null;
    }

    private Result(T data, boolean judge,Integer code) {
        this.code = code;
        this.status = judge ? "1" : "0";
        this.message = judge ? "成功！！！" : "失败！！！";
        this.data = data;
    }

    private Result(String message, T data, boolean judge) {
        this.code = judge ? 0 : -1;
        this.status = judge ? "1" : "0";
        this.message = message;
        this.data = data;
    }

    private Result(String message, boolean judge) {
        this.code = judge ? 0 : -1;
        this.status = judge ? "1" : "0";
        this.message = message;
        this.data = null;
    }

    private Result(ResultEnum resultEnum) {
        this.code = resultEnum.getCode();
        this.message = resultEnum.getMsg();
        this.msgTranslation = resultEnum.getMsgTranslation();
    }

    private Result(ResultEnum resultEnum, T data) {
        this.code = resultEnum.getCode();
        this.message = resultEnum.getMsg();
        this.msgTranslation = resultEnum.getMsgTranslation();
        this.data = data;
    }

    private Result(ResultEnum resultEnum, String message) {
        this.code = resultEnum.getCode();
        this.message = message;
        this.msgTranslation = resultEnum.getMsgTranslation();
    }

    private Result(ResultEnum resultEnum, String message, T data) {
        this.code = resultEnum.getCode();
        this.message = message;
        this.msgTranslation = resultEnum.getMsgTranslation();
        this.data = data;
    }

    private Result(Integer code, String message, boolean judgeState) {
        this.status = judgeState ? "1" : "0";
        this.code = code;
        this.message = message;
    }
}
